﻿package baseEngine.system
{
    import __AS3__.vec.*;
    import flash.display3D.*;
    import flash.geom.*;
    import flash.utils.*;
    import frEngine.math.*;
    import frEngine.shader.filters.*;
    import frEngine.shader.registType.*;
    import frEngine.shader.registType.base.*;

    final public class Device3D extends Object
    {
        public static const global:Matrix3D = new Matrix3D();
        public static const invGlobal:Matrix3D = new Matrix3D();
        public static const view:Matrix3D = new Matrix3D();
        public static const cameraGlobal:Matrix3D = new Matrix3D();
        public static const faceCameraMatrix3d:Matrix3D = new Matrix3D();
        public static const faceCameraQuaternion:Quaternion = new Quaternion();
        public static const identityMatrix3d:Matrix3D = new Matrix3D();
        public static const worldViewProj:Matrix3D = new Matrix3D();
        public static const worldView:Matrix3D = new Matrix3D();
        public static const proj:Matrix3D = new Matrix3D();
        private static const _vcConst1:Vector.<Number> = Device3D.Vector.<Number>([0, 0.5, 1, 2]);
        private static const _fcConst1:Vector.<Number> = Device3D.Vector.<Number>([0, 0.1, 1, 0.5]);
        public static const viewPortWH:Vector.<Number> = Device3D.Vector.<Number>([1024, 600, 0.01, 0.1]);
        public static var viewPortW:Number = 1024;
        public static var viewPortH:Number = 600;
        private static var _maxBonesPerVertex:int = 2;
        public static var maxBonesPerSurface:int = 37;
        public static const bones:Vector.<Number> = new Vector.<Number>(maxBonesPerSurface * 4 * 3);
        public static var viewProjValue:Matrix3D = new Matrix3D();
        public static const VcConst1Register2:VcParam = new VcParam(122, FilterName.viewPortRect, viewPortWH);
        public static const CameraViewProjRegister:MaxtrixParam = new MaxtrixParam(Context3DProgramType.VERTEX, 123, FilterName.viewProj, viewProjValue);
        public static const VcConst1Register:VcParam = new VcParam(127, FilterName.vcConst1, _vcConst1);
        public static const FcConst1Register:FcParam = new FcParam(27, FilterName.fcConst1, _fcConst1);
        public static const FcDirLightRegister:FcParam = new FcParam(26, FilterName.dirLight, null);
        public static const FcDirColorRegister:FcParam = new FcParam(25, FilterName.dirColor, null);
        public static const FcAmbientColorRegister:FcParam = new FcParam(24, FilterName.ambientColor, null);
        private static const vcReg:RegExp = new RegExp(FilterName.viewProj + "|" + FilterName.viewPortRect + "|" + FilterName.vcConst1, "gi");
        private static const fcReg:RegExp = new RegExp(FilterName.fcConst1 + "|" + FilterName.dirLight + "|" + FilterName.dirColor + "|" + FilterName.ambientColor, "gi");
        private static var _globleRegistsMap:Dictionary;

        public function Device3D()
        {
            return;
        }// end function

        public static function get maxBonesPerVertex() : int
        {
            return _maxBonesPerVertex;
        }// end function

        public static function set maxBonesPerVertex(param1:int) : void
        {
            if (param1 < 1 || param1 > 4)
            {
                throw new Error("maxBonesPerVertex should be from 1 to 4 but was set to " + param1);
            }
            _maxBonesPerVertex = param1;
            return;
        }// end function

        public static function setViewProj(param1:Matrix3D, param2:Context3D) : void
        {
            var _loc_3:MaxtrixParam = null;
            viewProjValue.copyFrom(param1);
            if (param2)
            {
                _loc_3 = Device3D.CameraViewProjRegister;
                param2.setProgramConstantsFromMatrix(_loc_3.type, _loc_3.index, _loc_3.value, true);
            }
            return;
        }// end function

        public static function setViewPortRect(param1:int, param2:int, param3:Context3D) : void
        {
            var _loc_4:ConstParamBase = null;
            var _loc_5:* = param1;
            viewPortW = param1;
            viewPortWH[0] = _loc_5;
            var _loc_5:* = param2;
            viewPortH = param2;
            viewPortWH[1] = _loc_5;
            if (param3)
            {
                _loc_4 = Device3D.VcConst1Register2;
                param3.setProgramConstantsFromVector(Context3DProgramType.VERTEX, _loc_4.index, _loc_4.value, 1);
            }
            return;
        }// end function

        public static function setVcConst(param1:int, param2:Number, param3:Context3D) : void
        {
            var _loc_4:ConstParamBase = null;
            _vcConst1[param1] = param2;
            if (param3)
            {
                _loc_4 = Device3D.VcConst1Register;
                param3.setProgramConstantsFromVector(Context3DProgramType.VERTEX, _loc_4.index, _loc_4.value, 1);
            }
            return;
        }// end function

        public static function setFcConst(param1:int, param2:Number, param3:Context3D) : void
        {
            var _loc_4:ConstParamBase = null;
            _fcConst1[param1] = param2;
            if (param3)
            {
                _loc_4 = Device3D.FcConst1Register;
                param3.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, _loc_4.index, _loc_4.value, 1);
            }
            return;
        }// end function

        public static function uploadGlobleParams(param1:Context3D) : void
        {
            var _loc_2:* = Device3D.CameraViewProjRegister;
            param1.setProgramConstantsFromMatrix(_loc_2.type, _loc_2.index, _loc_2.value, true);
            var _loc_3:* = Device3D.FcConst1Register;
            param1.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, _loc_3.index, _loc_3.value, 1);
            _loc_3 = Device3D.VcConst1Register;
            param1.setProgramConstantsFromVector(Context3DProgramType.VERTEX, _loc_3.index, _loc_3.value, 1);
            _loc_3 = Device3D.VcConst1Register2;
            param1.setProgramConstantsFromVector(Context3DProgramType.VERTEX, _loc_3.index, _loc_3.value, 1);
            return;
        }// end function

        private static function get globleRegistsMap() : Dictionary
        {
            if (!_globleRegistsMap)
            {
                _globleRegistsMap = new Dictionary(false);
                _globleRegistsMap[FilterName.viewProj] = Device3D.CameraViewProjRegister.registName;
                _globleRegistsMap[FilterName.viewPortRect] = Device3D.VcConst1Register2.registName;
                _globleRegistsMap[FilterName.vcConst1] = Device3D.VcConst1Register.registName;
                _globleRegistsMap[FilterName.fcConst1] = Device3D.FcConst1Register.registName;
                _globleRegistsMap[FilterName.dirLight] = Device3D.FcDirLightRegister.registName;
                _globleRegistsMap[FilterName.dirColor] = Device3D.FcDirColorRegister.registName;
                _globleRegistsMap[FilterName.ambientColor] = Device3D.FcAmbientColorRegister.registName;
            }
            return _globleRegistsMap;
        }// end function

        public static function replaceVertexCode(param1:String) : String
        {
            var _loc_4:String = null;
            var _loc_5:RegExp = null;
            var _loc_2:* = param1.match(vcReg);
            var _loc_3:* = globleRegistsMap;
            for each (_loc_4 in _loc_2)
            {
                
                _loc_5 = new RegExp(_loc_4, "gi");
                param1 = param1.replace(_loc_5, _loc_3[_loc_4]);
            }
            return param1;
        }// end function

        public static function replaceFragmentCode(param1:String) : String
        {
            var _loc_4:String = null;
            var _loc_5:RegExp = null;
            var _loc_2:* = param1.match(fcReg);
            var _loc_3:* = globleRegistsMap;
            for each (_loc_4 in _loc_2)
            {
                
                _loc_5 = new RegExp(_loc_4, "gi");
                param1 = param1.replace(_loc_5, _loc_3[_loc_4]);
            }
            return param1;
        }// end function

    }
}
